dd.legacy.extend({
    init:function()
    {
        dd.extend({
            fn:{
                /**
                 * Parameters are used to store data on a dom element
                 * @namespace dd.fn.parameters
                 * @set {object}
                 *   the parameters off the dom element
                 *  @returns dd.fn.e._ddParameters
                 */
                event:function(o, parameters)
                {
                    if(parameters)
                        this.e._ddParameters = parameters;
                    else
                        this.e._ddParameters = {};
                    var a = {"onLoad":false,
                             "onResize":false,
                             "onClick":false,
                             "onMouseDown":false,
                             "onMouseUp":false,
                             "onMouseMove":false,
                             "onMouseOver":false,
                             "onMouseOut":false,
                             "onScroll":false,
                             "onKeyDown":false,
                             "onKeyUp":false};
                    o.scope = this.scope;
                    o.scope.extend = function(o)
                    {
                        for(i in o)
                            this[i] = o[i];
                    }
                    for(i in a)
                    {
                        if(o[i] != undefined)
                        {
                            a[i] = true;
                            this.e[i.toLowerCase()] = this.eventHandler(o, i);
                        }
                    }
                    // MouseMove requires MouseUp and MouseDown defined
                    var e = "onMouseDown";
                    if(a["onMouseMove"] && !a[e])
                    {
                        o[e] = function(){};
                        o[e].r = true;
                        this.e[e.toLowerCase()] = this.eventHandler(o, e);
                    }
                    e = "onMouseUp";
                    if(a["onMouseMove"] && !a[e])
                    {
                        o[e] = function(){};
                        o[e].r = true;
                        this.e[e.toLowerCase()] = this.eventHandler(o, e);
                    }
                },
                /**
                 * Handles the events
                 * @namespace dd.fn.eventHandler
                 * @function
                 *  Select a dom element by id attribute
                 *  @param o {object} The event object
                 *  @param type {string} The event type. Ex: "onClick"
                 *  @returns If the event should Propigate
                 */
                eventHandler:function(o, type)
                {
                    return function(e)
                    {
                        o.scope.extend(o.scope.fn.eventHandlers[type].call(o.scope.fn, e, this));
                        if(!(o.scope.fn.event.clickVoid && type == "onClick"))
                            var r = o[type].call(o.scope);
                        else if(type == "onClick")
                            o.scope.fn.event.clickVoid = false;
                        return o[type].r == undefined ? r == null ? false : r : o[type].r;
                    };
                },
                eventHandlers:{
                    onLoad:function(e, ele)
                    {
                        var r = {
                            parameters:{},
                            window:{
                                width:window.innerWidth,
                                height:window.innerHeight
                            }
                        };
                        for(var i in ele._ddParameters)
                            r.parameters[i] = ele._ddParameters[i];
                        return r;
                    },
                    onResize:function(e, ele)
                    {
                        return {
                            window:{
                                width:window.innerWidth,
                                height:window.innerHeight
                            },
                            width:e.innerWidth,
                            height:e.innerHeight
                        };
                    },
                    onClick:function(e, ele)
                    {
                        var r = {
                            parameters:{},
                            element:ele,
                            target:{
                                id:e.target.id
                            },
                            mouse:
                            {
                                x:e.clientX - e.target.offsetLeft + window.scrollX,
                                y:e.clientY - e.target.offsetTop + window.scrollY
                            }
                        };
                        for(var i in ele._ddParameters)
                            r.parameters[i] = ele._ddParameters[i];
                        return r;
                    },
                    onScroll:function(e, ele)
                    {
                        var r = {
                            parameters:{},
                            scroll:{
                                x:ele.scrollLeft,
                                y:ele.scrollTop
                            }
                        };
                        for(var i in ele._ddParameters)
                            r.parameters[i] = ele._ddParameters[i];
                        return r;
                    },
                    onMouseDown:function(e, ele)
                    {
                        this.event.clickVoid = false;
                        this.event.oldX = e.clientX;
                        this.event.oldY = e.clientY;
                        this.event.currentX = e.clientX;
                        this.event.currentY = e.clientY;
                        this.event.mouseDown = true;
                        var ol = ele.offsetLeft == undefined ? 0 : ele.offsetLeft;
                        var ot = ele.offsetTop == undefined ? 0 : ele.offsetTop;
                        var r = {
                            mouse:
                            {
                                x:e.clientX + window.scrollX - ol,
                                y:e.clientY + window.scrollY - ot
                            }
                        };
                        r.target = e.target;
                        return r;
                    },
                    onMouseMove:function(e)
                    {
                        // Other
                        var changeX = e.clientX - this.event.currentX;
                        var changeY = e.clientY - this.event.currentY;
                        var cX = e.clientX - this.event.oldX;
                        var cY = e.clientY - this.event.oldY;
                        if(cX !== 0 || cY !== 0)
                            this.event.clickVoid = true;
                        this.event.currentX = e.clientX;
                        this.event.currentY = e.clientY;
                        return {
                            window:{
                                // TODO: Bottom / Top
                                scroll:{
                                    get top()
                                    {
                                        return window.scrollY;
                                    },
                                    set top(v)
                                    {
                                        window.scrollY = v;
                                        return window.scrollY;
                                    },
                                    get left()
                                    {
                                        return window.scrollX;
                                    },
                                    set left(v)
                                    {
                                        window.scrollX = v;
                                        return window.scrollX;
                                    }
                                },
                                width:window.innerWidth,
                                height:window.innerHeight
                            },
                            mouse:
                            {
                                x:e.clientX,
                                y:e.clientY,
                                changeX:changeX,
                                changeY:changeY,
                                pageX:e.pageX,
                                pageY:e.pageY,
                                offsetX:e.clientX - this.event.oldX,
                                offsetY:e.clientY - this.event.oldY,
                                down:this.event.mouseDown
                            }
                        };
                    },
                    onMouseUp:function(e)
                    {
                        this.event.mouseDown = false;
                        return {
                            clientX:e.clientX,
                            clientY:e.clientY,
                            mouse:
                            {
                                offsetX:100,
                                offsetY:200
                            }
                        };
                    },
                    onMouseOver:function(e, ele)
                    {
                        var r = {
                            parameters:{},
                            element:ele,
                            clientX:e.clientX,
                            clientY:e.clientY,
                            mouse:
                            {
                                offsetX:100,
                                offsetY:200
                            }
                        };
                        for(var i in ele._ddParameters)
                            r.parameters[i] = ele._ddParameters[i];
                        return r;
                    },
                    onMouseOut:function(e, ele)
                    {
                        var r = {
                            parameters:{},
                            element:ele,
                            clientX:e.clientX,
                            clientY:e.clientY,
                            mouse:
                            {
                                offsetX:100,
                                offsetY:200
                            }
                        };
                        for(var i in ele._ddParameters)
                            r.parameters[i] = ele._ddParameters[i];
                        return r;
                    },
                    onKeyDown:function(e)
                    {
                        var c = String.fromCharCode(e.keyCode);
                        if(!e.shiftKey)
                            c = c.toLowerCase();
                        return {
                            keyCode:e.keyCode,
                            keyCharacter:c,
                            ctrlKey:e.ctrlKey,
                            altKey:e.altKey
                        }
                    },
                    onKeyUp:function(e)
                    {
                        var c = String.fromCharCode(e.keyCode);
                        if(!e.shiftKey)
                            c = c.toLowerCase();
                        return {
                            keyCode:e.keyCode,
                            keyCharacter:c,
                            ctrlKey:e.ctrlKey,
                            altKey:e.altKey
                        }
                    }
                },
                setAttribute:function(property, value)
                {
                    return this.e.setAttribute(property, value);
                },
                /**
                 * Parameters are used to store data on a dom element
                 * @namespace dd.fn.parameters
                 * @get
                 *  Gets the parameters from the dom element
                 *  @returns {object} dd.fn.e._ddParameters
                 */
                get parameters()
                {
                    if(typeof(this.e._ddParameters) == "undefined")
                        this.e._ddParameters = {};
                    return this.e._ddParameters;
                },
                /**
                 * Parameters are used to store data on a dom element
                 * @namespace dd.fn.parameters
                 * @set {object}
                 *   the parameters off the dom element
                 *  @returns dd.fn.e._ddParameters
                 */
                set parameters(v)
                {
                    this.e._ddParameters = v;
                    return this.e._ddParameters;
                },
                /**
                 * Set a style
                 * @namespace dd.fn.setStyle
                 * @function
                 *  @param obj {object} Ex: {"textAlign":"center","color":"#D4D4D4"}
                 *  @returns {object} dd.fn
                 */
                setStyle:function(o)
                {
                    for(var i in o)
                        this.e.style[i] = o[i];
                    return dd.fn;
                },
                /**
                 * Set a style
                 * @todo Still needs to be scripted in
                 * @namespace dd.fn.addStyle
                 * @function
                 *  @param name {string} Ex: "textAlign"
                 *  @param value {string} Ex: "center"
                 *  @returns {object} dd.fn
                 */
                addStyle:function(name, value)
                {
                    
                    return dd.fn;
                },
                /**
                 * Set a style
                 * @todo Still needs to be scripted in
                 * @namespace dd.fn.setStyle
                 * @function
                 *  @param name {string} Ex: "textAlign"
                 *  @returns {object} dd.fn
                 */
                removeStyle:function(name)
                {
                    
                    return dd.fn;
                },
                focus:function()
                {
                    this.e.focus();
                    return dd.fn;
                },
                selectAll:function()
                {
                    this.e.select();
                    return dd.fn;
                },
                get display()
                {
                    if(this.e.style.display)
                        return this.e.style.display;
                    else
                        return "block";
                },
                set display(v)
                {
                    this.e.style.display = v;
                    return this.e.style.display;
                },
                get visible()
                {
                    if(this.e.style.visible)
                        return (this.e.style.visible == "visible");
                    else
                        return "visible";
                },
                set visible(v)
                {
                    this.e.style.visible = (v == true ? "visible" : "hidden");
                    return v;
                },
                get scrollTop()
                {
                    return this.e.scrollTop;
                },
                set scrollTop(v)
                {
                    this.e.scrollTop = v;
                    return this.e.scrollTop;
                },
                get text()
                {
                    if(this.e.firstChild)
                        return this.e.firstChild.nodeValue;
                    else
                        return "";
                },
                set text(s)
                {
                    if(this.e.firstChild)
                        this.e.firstChild.nodeValue = s;
                    else
                        this.e.appendChild(document.createTextNode(s));
                    return this.e.firstChild.nodeValue;
                },
                get width()
                {
                    return this.e.offsetWidth;
                },
                set width(w)
                {
                    this.e.style.width = w + "px";
                    return this.e.offsetWidth;
                },
                get height()
                {
                    return this.e.offsetHeight;
                },
                set height(h)
                {
                    this.e.style.height = h + "px";
                    return this.e.offsetHeight;
                },
                get top()
                {
                    if(this.e.style.top == "")
                        return 0;
                    else
                        return parseInt(this.e.style.top.match(/(-?\d+)px/i)[1]);
                },
                set top(t)
                {
                    this.e.style.top = t + "px";
                    return parseInt(this.e.style.top.match(/(-?\d+)px/i)[1]);
                },
                get left()
                {
                    return this.e.offsetLeft;
                },
                set left(l)
                {
                    this.e.style.left = l + "px";
                    return this.e.offsetLeft;
                },
                get opacity()
                {
                    if(this.e.style.opacity == "")
                        return 1;
                    else
                        return parseInt(this.e.style.opacity);
                },
                set opacity(v)
                {
                    this.e.style.opacity = v;
                    return parseInt(this.e.style.opacity);
                },
                get className()
                {
                    return this.e.style.className;
                },
                set className(n)
                {
                    this.e.className = n;
                    return this.e.className;
                },
                get value()
                {
                    if(this.e.value)
                        return this.e.value;
                    else
                        return "";
                },
                set value(v)
                {
                    this.e.value = v;
                    return this.e.value;
                },
                toggle:function(o)
                {
                    var nia = true;
                    for(var i in o.value)
                        if(o.value[i] == this.text)
                            nia = false;
                    for(var i = 0; i<= o.value.length; i++)
                    {
                        if(i == o.value.length - 1 || nia)
                        {
                            this.text = o.value[0];
                        }
                        else if(o.value[i] == this.text)
                        {
                            this.text = o.value[i + 1];
                            break;
                        }
                    }
                },
                animate:function()
                {
                    
                },
                animateHandler:function()
                {
                    
                },
                get parent()
                {
                    return dd(this.e.parentNode);
                }
            },
            /**
             * VERY IMPORTANT HANDLES NAMESPACE!
             */
            ns:function(s)
            {
                
            },
            screen:{
                get width()
                {
                    return window.availWidth;
                },
                get height()
                {
                    return window.availHeight;
                }
            },
            preferences:{
                _data:{},
                load:function()
                {
                    for(i in this)
                    {
                        if(i != "save" && i != "load" && i != "_data")
                            delete(this[i]);
                    }
                    var the_cookie = document.cookie.split(';');
                    if(the_cookie[0])
                    {
                        this._data = JSON.parse(unescape(the_cookie[0]));
                    }
                    for(i in this._data)
                        this[i] = this._data[i];
                    return this._data;
                },
                save:function()
                {
                    var d = new Date(2020, 02, 02);
                    var p = '/';
                    for(i in this)
                    {
                        if(i != "save" && i != "load" && i != "_data")
                            this._data[i] = this[i];
                    }
                    document.cookie = escape(JSON.stringify(this._data))
                                      + ';path=' + p
                                      + ';expires=' + d.toUTCString();
                }
            },
            project:{},
            addProject:function(project, folder)
            {
                if(typeof(folder) == "undefined")
                    folder = "scripts/" + project;
                this._project = {
                    "name":project,
                    "folder":folder
                };
                this.addProjectFile("", folder);
            },
            _files:[],
            addProjectFile:function(file, folder)
            {
                if(typeof(folder) == "undefined")
                    folder = this._project.folder;
                this._loadFile(this._files.push({
                    "namespace":this._project.name + (file == "" ? "" : "." + file),
                    "folder":(folder == "" ? "" : folder + "/")
                }) - 1);
            },
            _modules:[],
            addModule:function(file, folder)
            {
                if(typeof(folder) == "undefined")
                {
                    folder = "scripts/dd/";
                    var headID = document.getElementsByTagName("head")[0].children;
                    for(var i in headID)
                        if(headID[i].tagName == "script")
                            if(/dd\.js$/.test(headID[i].getAttribute('src')))
                                folder = /(.*)dd\.js$/.exec(headID[i].getAttribute('src'))[1];
                }
                this._loadFile(this._files.push({
                    "namespace":"dd." + file,
                    "folder":folder
                }) - 1);
            },
            _loadFilesCount:0,
            _loadFile:function(i)
            {
                var n = this._files[i].namespace,
                    f = this._files[i].folder,
                    ns = n.split(/\./);
                if(ns[0] == "dd")
                {
                    ns.shift();
                    dd.extend(ns.join("."), {
                        "extend":dd.extend,
                        "_namespace":ns.join(".")
                    });
                    dd.addJS(f + n + ".js");
                    clearInterval(dd._loadInterval);
                    dd._loadFiles();
                }
                else
                {
                    dd.extend("project." + ns.join("."), {
                        "func":(function(s){
                            return function(o){dd.extend(s, o);}
                            })("project." + ns.join(".")),
                        "_namespace":"project." + ns.join(".")
                    });
                    dd.addJS(f + n + ".js");
                    clearInterval(dd._loadInterval);
                    dd._loadFiles();
                }
            },
            _loadFiles:function()
            {
                for(var i = dd._loadFilesCount; i < dd._files.length; i++)
                {
                    var n = dd._files[i].namespace,
                    f = dd._files[i].folder,
                    ns = n.split(/\./);
                    if(ns[0] == "dd")
                    {
                        ns.shift();
                        var file = dd;
                        for(var j = 0; j < ns.length; j++)
                            file = file[ns[j]];
                        if(typeof(file.init) == "undefined")
                        {
                            dd._loadInterval = setTimeout(dd._loadFiles, 200);
                            break;
                        }
                        file.init.call(file);
                        dd._loadFilesCount++;
                    }
                    else
                    {
                        var file = dd.project;
                        for(var j = 0; j < ns.length; j++)
                            if(ns[j] != "")
                                file = file[ns[j]];
                        if(typeof(file.init) == "undefined")
                        {
                            dd._loadInterval = setTimeout(dd._loadFiles, 200);
                            break;
                        }
                        file.init.call(file);
                        dd._loadFilesCount++;
                    }
                }
            },
            _load:function()
            {
                dd.html = document.getElementsByTagName("html")[0];
                dd.html.head = document.getElementsByTagName("head")[0];
                dd.html.body = document.getElementsByTagName("body")[0];
            },
            _ns:{
                "svg":"http://www.w3.org/2000/svg"
            }
        });
    }
});